;__CUBPRPB_________________________________________________________________________________________
;
;	PREP THE IDE DRIVE (DRIVE "B") FOR CUBIX
;
;	WRITTEN BY: DAN WERNER -- 12/8/2009
;__________________________________________________________________________________________________
;__________________________________________________________________________________________________
;
; CONFIGURATION
;__________________________________________________________________________________________________
;
;
USEDSKY		.EQU	01		; NONZERO = USE DSKY DEVICE FOR DISK IO STATUS
				
;
;
;__________________________________________________________________________________________________
;
; DATA CONSTANTS
;__________________________________________________________________________________________________
;REGISTER		IO PORT		; FUNCTION
PPIA		.equ	$00		; 8255 PORT A
PPIB		.equ	$01		; 8255 PORT B
PPIC		.equ	$02		; 8255 PORT C
PPICONT		.equ	$03		; 8255 CONTROL PORT 

BDOS		.equ	$0005		; BDOS ENTRY

; IDE REGISTER		IO PORT		; FUNCTION
IDELO:		 .EQU 	20H		; DATA PORT (LOW BYTE)
IDEERR:		 .EQU 	21H		; READ: ERROR REGISTER; WRITE: PRECOMP
IDESECTC:	 .EQU 	22H		; SECTOR COUNT
IDESECTN:	 .EQU 	23H		; SECTOR NUMBER
IDECYLLO:	 .EQU 	24H		; CYLINDER LOW
IDECYLHI:	 .EQU 	25H		; CYLINDER HIGH
IDEHEAD:	 .EQU 	26H		; DRIVE/HEAD
IDESTTS:	 .EQU 	27H		; READ: STATUS; WRITE: COMMAND
IDEHI:		 .EQU 	28H		; DATA PORT (HIGH BYTE)
IDECTRL:	 .EQU 	2EH		; READ: ALTERNATIVE STATUS; WRITE; DEVICE CONTROL
IDEADDR:	 .EQU 	2FH		; DRIVE ADDRESS (READ ONLY)
CR		.EQU	$0D		; CARRIAGE RETURN CHARACTER
LF		.EQU	$0A		; LINE FEED CHARACTER
END		.EQU	'$'		; LINE TERMINATOR FOR CP/M STRINGS



	.org	$0100


;__________________________________________________________________________________________________
;
; 	MAIN 
;__________________________________________________________________________________________________
MAIN:
					; BLANK OUT FIRST 257 SECTORS
	LD	HL,SECTOR_BUFFER	;
	LD	BC,$0200		;
	LD	A,$00			;
	CALL	FILL_MEM		;
	
	LD	A,$00			;
	LD	(SECTOR),A		;
	LD	(HEAD),A		;
	LD	A,$01			;
	LD	(TRACK),A		;
	CALL	WRITE_1			;
	
	LD	A,$00			;
	LD	(SECTOR),A		;
	LD	(HEAD),A		;
	LD	(TRACK),A		;
MAIN_1:
	CALL	WRITE_1			;
	LD	A,(SECTOR)		;
	ADD	A,1			;
	LD	(SECTOR),A		;
	JP	NZ,MAIN_1		;

	LD	HL,SECTOR_BUFFER	;
	LD	BC,$0000		;	
MAIN_2:
	INC	BC			;
	LD	(HL),B			;
	INC	HL			;
	LD	(HL),C			;
	INC	HL			;
	LD	A,B			;
	CP	$02			;
	JP	NZ,MAIN_2		;
	
	LD	A,$0FF			;
	LD	(SECTOR_BUFFER),A	;
	LD	(SECTOR_BUFFER+1),A	;
	LD	A,$01			;
	LD	(SECTOR),A		;
	LD	A,$00			;
	LD	(HEAD),A		;
	LD	(TRACK),A		;
	CALL	WRITE_1			;
	
	LD	HL,SECTOR_BUFFER	;
	LD	BC,$0200		;
	LD	A,$00			;
	CALL	FILL_MEM		;

	LD	A,$0FF			;
	LD	(SECTOR_BUFFER),A	;
	LD	(SECTOR_BUFFER+1),A	;
	LD	A,$02			;
	LD	(SECTOR),A		;
	LD	A,$00			;
	LD	(HEAD),A		;
	LD	(TRACK),A		;
	CALL	WRITE_1			;

	
	LD	DE,MSG_END		;
	LD	C,09H			; CP/M WRITE END STRING TO CONSOLE CALL
	CALL	0005H			;
					;
	LD	C,00H			; CP/M SYSTEM RESET CALL
	CALL	0005H			; RETURN TO PROMPT

MSG_END:
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.TEXT	"END CUBIX ZIP PREP PROGRAM"
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.DB	END			; LINE TERMINATOR


	
	
;__WRITE_1__________________________________________________________________________________________ 
;
;	WRITE A SECTOR TO DRIVE 1
;___________________________________________________________________________________________________
;
WRITE_1:
	LD	A,10H			; SET TO SECONDARY DEVICE
	LD	(IDEDEVICE),A		;
					;
	LD	A,(SECTOR)		;
	LD	(LBA_TARGET_LO),A 	; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ
	LD	A,(TRACK)		;
	LD	(LBA_TARGET_LO+1),A	; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ
	LD	A,(HEAD)		;
	LD	(LBA_TARGET_HI),A 	; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ
	LD	A,00H			;
	LD	(LBA_TARGET_HI+1),A	; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ
						
	CALL	ATAPI_WRITE_SECTOR	; WRITE THE IDE HARD DISK SECTOR

	RET

	
;__FILL_MEM______________________________________________________________________________________________________________________ 
;
;	Function	: fill memory with a value
;      	Input		: HL = start address block
;			: BC = length of block
;			: A = value to fill with
;	Uses		: DE, BC
;________________________________________________________________________________________________________________________________
;

FILL_MEM:

					; HL = start address of block
					; DE = HL + 1
	ld	e,l			;
	ld	d,h			;
	inc	de			;
					; initialise first byte of block
					; with data byte (&00)
					; with data byte in A
	ld	(hl),A			;
	ldir				;
	RET				; return to caller
		
	

;___ATAPI_WAIT_BUSY_READY________________________________________________________________________________
;
;	WAIT FOR ATAPI CHANNEL TO BE READY
;________________________________________________________________________________________________________			
ATAPI_WAIT_BUSY_READY:
	LD	DE,0			; CLEAR OUT DE
ATAPI_WBSY:				;
	LD	B,0F0H			; SETUP TIMEOUT
ATAPI_DLP:				;
	DJNZ	ATAPI_DLP		; 
	INC	DE			;
	LD	A,D			;
	OR	E			;
	JR	Z,ATAPI_TO		;
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	010000000b		; MASK OFF BUSY BIT
	JR	NZ,ATAPI_WBSY		; WE WANT BUSY(7) TO BE 0 
	SCF				; CARRY 1 = OK
	RET				;
ATAPI_TO:				;
	XOR	A			; CARRY 0 = TIMED OUT
	RET				;
	
;___IDE_WAIT_DRQ_READY___________________________________________________________________________________
;
;	WAIT FOR IDE CHANNEL TO BE READY
;________________________________________________________________________________________________________			
IDE_WAIT_DRQ_READY:
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	000001000b		; MASK OFF RDY BIT
	JR	Z,IDE_WAIT_DRQ_READY	; WE WANT DRQ(3) TO BE 1
	RET

;___IDE_WAIT_DRQ_ZERO____________________________________________________________________________________
;
;	WAIT FOR IDE DRQ TO BE ZERO
;________________________________________________________________________________________________________			
IDE_WAIT_DRQ_ZERO:
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	000001000b		; MASK OFF RDY BIT
	JR	NZ,IDE_WAIT_DRQ_ZERO	; WE WANT DRQ(3) TO BE 0
	RET

;___IDE_WAIT_BUSY_READY___________________________________________________________________________________
;
;	WAIT FOR IDE CHANNEL TO BE READY
;________________________________________________________________________________________________________			
IDE_WAIT_BUSY_READY:
	LD	DE,0			; CLEAR DE
IDE_WBSY:				;
	LD	B,5			; SETUP TIMEOUT
IDE_DLP:				;
	DEC	B			;
	JP	NZ,IDE_DLP		;
	INC	DE			;
	LD	A,D			;
	OR	E			;
	JP	Z,IDE_TO		;
	IN	A,(IDESTTS)		; READ ERROR REG
	AND	011000000b		; MASK OFF BUSY AND RDY BITS
	XOR	001000000b		; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1
	JP	NZ,IDE_WBSY		;
	SCF				; CARRY 1 = OK
	RET
IDE_TO:
	XOR	A			; CARRY 0 = TIMED OUT
	RET
	
;___IDE_TEST_ERROR_______________________________________________________________________________________
;
;	CHECK FOR IDE ERROR CONDITION
;________________________________________________________________________________________________________			
IDE_TEST_ERROR:
	SCF				;
	IN	A,(IDESTTS)		;
	LD	B,A			; 
	AND	000000001b		; TEST ERROR BIT
	SCF				; 
	RET	Z			;
	LD	A,B			; 
	AND	000100000b		;
	SCF				;
	JP	NZ,IDE_ERR		; TEST WRITE ERROR BIT
	IN	A,(IDEERR)		; READ ERROR FLAGS
IDE_ERR:
	OR	A			; CARRY 0 = ERROR
	RET				; IF A = 0, IDE BUSY TIMED OUT

;___IDE_WAIT_BUFFER_______________________________________________________________________________________
;
;	WAIT FOR DATA BUFFER READY
;________________________________________________________________________________________________________			
IDE_WAIT_BUFFER:
	LD	DE,0			;
IDE_WDRQ:				;
	LD	B,5			;
IDE_BLP:				;
	DEC	B			;
	JP	NZ,IDE_BLP		;	
	INC	DE			;
	LD	A,D			;
	OR	E			;
	JP	Z,IDE_TO2		;
	IN	A,(IDESTTS)		; WAIT FOR DRIVE'S 512 BYTE READ BUFFER 
	AND	000001000b		; TO FILL (OR READY TO FILL)
	JP	Z,IDE_WDRQ		;
	SCF				; CARRY 1 = OK
	RET				;
IDE_TO2:				;
	XOR	A			; CARRY 0 = TIMED OUT
	RET				;

;___IDE_READ_BUFFER_______________________________________________________________________________________
;
;	READ IDE BUFFER
;________________________________________________________________________________________________________			
IDE_READ_BUFFER:
	PUSH	HL			;
	LD	HL,SECTOR_BUFFER	;
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
IDEBUFRD:				;
	IN	A,(IDELO)		; LOW BYTE OF WORD FIRST	
	LD	(HL),A			;
	IN	A,(IDEHI)		; THEN HIGH BYTE OF WORD
	INC	HL			;
	LD	(HL),A			;
	INC	HL			;
	DEC	B			;
	JP	NZ,IDEBUFRD		;
	POP	HL			;
	RET

;___IDE_WRITE_BUFFER_______________________________________________________________________________________
;
;	WRITE TO IDE BUFFER
;________________________________________________________________________________________________________			
IDE_WRITE_BUFFER:
	PUSH	HL			;
	LD	HL,SECTOR_BUFFER	;
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
IDEBUFWT:				;
	INC	HL			;
	LD	A,(HL)			;
	DEC	HL			;
	OUT	(IDEHI),A		; SET UP HIGH LATCHED BYTE BEFORE
	LD	A,(HL)			;
	OUT	(IDELO),A		; WRITING WORD WITH WRITE TO LOW BYTE
	INC	HL			;
	INC	HL			;
	DEC	B			;
	JP	NZ,IDEBUFWT		;
	POP	HL			;
	RET		
	
;___IDE_SETUP_LDA________________________________________________________________________________________
;
;	SETUP IDE DRIVE FOR LDA OPERATION
;________________________________________________________________________________________________________			
IDE_SETUP_LBA:
	LD	A,(LBA_TARGET_LO) 	; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ
	LD	(IDE_LBA0),A		;
	LD	A,(LBA_TARGET_LO+1)	; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ
	LD	(IDE_LBA1),A		;
	LD	A,(LBA_TARGET_HI) 	; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ
	LD	(IDE_LBA2),A		;
	LD	A,(LBA_TARGET_HI+1)	; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ
	AND	000001111b		; ONLY LOWER FOUR BITS ARE VALID
	ADD	A,011100000b		; ENABLE LBA BITS 5:7=111 IN IDE_LBA3
	LD	(IDE_LBA3),A		;
					; READ IDE HD SECTOR
	LD	A,1			;
	OUT	(IDESECTC),A		; SET SECTOR COUNT = 1	
					;	
	LD	A,(IDE_LBA0)		;
	OUT	(IDESECTN),A		; SET LBA 0:7
					;
	LD	A,(IDE_LBA1)		;
	OUT	(IDECYLLO),A		; SET LBA 8:15
					;
	LD	A,(IDE_LBA2)		;
	OUT	(IDECYLHI),A		; SET LBA 16:23
					;
	LD	A,(IDE_LBA3)		;
	AND	000001111b		; LOWEST 4 BITS USED ONLY
	OR	011100000b		; TO ENABLE LBA MODE
	OUT	(IDEHEAD),A		; SET LBA 24:27 + BITS 5:7=111
	.IF	USEDSKY
	CALL	IDESEGDISPLAY		;
	.ENDIF
	RET	

;___ATAPI_SOFT_RESET_____________________________________________________________________________________
;
;	RESET ATAPI BUS
;________________________________________________________________________________________________________			
ATAPI_SOFT_RESET:
	LD	A,000001110b		;NO INTERRUPTS, RESET DRIVE = 1
	OUT	(IDECTRL),A		;
	CALL	DELAY24			;
	LD	A,000001010b		;NO INTERRUPTS, RESET DRIVE = 0
	OUT	(IDECTRL),A		;
	CALL	ATAPI_WAIT_BUSY_READY	;
	RET	NC			; ERROR, RETURN
	CALL	ATAPI_DEVICE_SELECTION	;
	CALL	DELAY24			;
	CALL 	REQUEST_SENSE_LOOP	;
	RET

;___REQUEST_SENSE_LOOP____________________________________________________________________________________
;
;	ATAPI_REQUEST SENSE DATA
;_________________________________________________________________________________________________________			
REQUEST_SENSE_LOOP:
	LD	HL,ATAPI_REQUEST_SENSE	;
	CALL	ATAPI_SEND_PACKET	;
	CALL	ATAPI_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
REQUEST_SENSE_LOOP1:			;
	IN	A,(IDELO)		;
	INC	IX			;
	IN	A,(IDEHI)		;
	INC	IX			;
	DJNZ	REQUEST_SENSE_LOOP1	;
	RRD				; DELAY ONLY
	IN	A,(IDESTTS)		;READ ERROR REG
	AND	000000001b		;MASK OFF BIT
	JR	NZ,REQUEST_SENSE_LOOP	;
	RET

;___ATAPI_DEVICE_SELECTION________________________________________________________________________________
;
;	ATAPI DEVICE SELECTION
;_________________________________________________________________________________________________________			
ATAPI_DEVICE_SELECTION:

	LD	A,(IDEDEVICE)		; SELECTS DEVICE
	OR	0A0H			;
	OUT	(IDEHEAD),A		;	
	RET				;



;__ATAPI_READ_SECTOR_____________________________________________________________________________________________________________ 
;  READ ATAPI SECTOR   
;
;   D E H L = SECTOR (DOUBLE WORD) TO READ 
;________________________________________________________________________________________________________________________________ 
ATAPI_READ_SECTOR:
	LD	A,(LBA_TARGET_LO)	; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ
	LD	(READ_DISK_PACKET+5),A	;
	LD	A,(LBA_TARGET_LO+1)	; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ
	LD	(READ_DISK_PACKET+4),A	;
	LD	A,(LBA_TARGET_HI)	; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ
	LD	(READ_DISK_PACKET+3),A	;
	LD	A,(LBA_TARGET_HI+1)	; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ
	LD	(READ_DISK_PACKET+2),A	;
	.IF	USEDSKY
	CALL	ATAPISEGDISPLAY		;
	.ENDIF
	CALL	REQUEST_SENSE_LOOP	; GET ATAPI SENSE CODES TO CLEAR ERRORS
	LD	HL,READ_DISK_PACKET	; SET POINTER TO READ SECTOR PACKET
	CALL	ATAPI_SEND_PACKET	; SEND PACKET COMMAND
	CALL	ATAPI_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
	LD	IX,SECTOR_BUFFER	;
	IN	A,(IDESTTS)		; READ  REG
	AND	000001000b		; MASK OFF BIT
	CP	08H			; IS DATA WAITING?
	JR	NZ,ATAPI_READ_DATA_EXIT	; NO, EXIT
ATAPI_READ_DATA_LOOP:
	IN	A,(IDELO)		;
	LD	(IX+0),A		;
	INC	IX			;
	IN	A,(IDEHI)		;
	LD	(IX+0),A		;
	INC	IX			;
	DJNZ	ATAPI_READ_DATA_LOOP	;
ATAPI_READ_DATA_EXIT:
	SCF				; CARRY = 1 ON RETURN = OPERATION OK
	RET				;



;__ATAPI_WRITE_SECTOR_____________________________________________________________________________________________________________ 
;  WRITE ATAPI SECTOR   
;
;   D E H L = SECTOR (DOUBLE WORD) TO WRITE 
;________________________________________________________________________________________________________________________________ 
ATAPI_WRITE_SECTOR:

	LD	A,(LBA_TARGET_LO)	; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ
	LD	(WRITE_DISK_PACKET+5),A	;
	LD	A,(LBA_TARGET_LO+1)	; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ
	LD	(WRITE_DISK_PACKET+4),A	;
	LD	A,(LBA_TARGET_HI)	; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ
	LD	(WRITE_DISK_PACKET+3),A	;
	LD	A,(LBA_TARGET_HI+1)	; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ
	LD	(WRITE_DISK_PACKET+2),A	;
	.IF	USEDSKY
	CALL	ATAPISEGDISPLAY		;
	.ENDIF
	CALL 	REQUEST_SENSE_LOOP	;
	LD	HL,WRITE_DISK_PACKET	; SET POINTER TO WRITE PACKET COMMAND
	CALL	ATAPI_SEND_PACKET	; SEND THE PACKET COMMAND						
	CALL	ATAPI_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	LD	B,0			; 256 WORDS (512 BYTES PER SECTOR)
	LD	IX,SECTOR_BUFFER	;
ATAPI_WRITE_DATA_LOOP:
	IN	A,(IDESTTS)		; READ  REG
	LD	A,(IX+0)		;
	PUSH    AF			;
	INC	IX			;
	LD	A,(IX+0)		;
	OUT	(IDEHI),A		;
	POP	AF			;
	OUT	(IDELO),A		;
	INC	IX			;
	DJNZ	ATAPI_WRITE_DATA_LOOP	;
	SCF				; CARRY = 1 ON RETURN = OPERATION OK
	RET				;




;__ATAPI_SEND_PACKET_____________________________________________________________________________________________________________ 
;  SEND PACKET POINTED TO BY HL TO ATAPI DRIVE   
;
;________________________________________________________________________________________________________________________________ 
ATAPI_SEND_PACKET:

	CALL	ATAPI_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	CALL	IDE_WAIT_DRQ_ZERO	;
					;
	LD	A,0AH			;
	OUT	(IDECTRL),A		; DISABLE INT
	LD	A,00H			;
	OUT	(IDEERR),A		;
	LD	A,00H			;
	OUT	(IDESECTC),A		; 
	LD	A,00H			;
	OUT	(IDESECTN),A		;
	LD	A,00H			;
	OUT	(IDECYLLO),A		; 
	LD	A,60H			;
	OUT	(IDECYLHI),A		; 
	LD	A,(IDEDEVICE)		;
	OUT	(IDEHEAD),A		; BIT 4 SELECTS DEVICE
	LD	A,0A0H			;
	OUT	(IDESTTS),A		;
					;
	CALL	IDE_WAIT_DRQ_READY	; MAKE SURE DRIVE IS READY TO PROCEED
					;
	LD	B,6			; SEND 12 BYTES (6 WORDS)
					;
ATAPI_SEND_PACKET_LOOP:
	LD	A,(HL)			; GET BYTE
	LD	D,A			; STORE LOW BYTE IN D
	INC	HL			; INC POINTER
	LD	A,(HL)			; GET HIGH BYTE
	OUT	(IDEHI),A		; STORE HIGH BYTE
	LD	A,D			; MOVE LOW BYTE INTO A
	OUT	(IDELO),A		; STORE LOW BYTE
	INC	HL			; INC POINTER
	IN	A,(IDECTRL)		; GET STATUS
	DJNZ	ATAPI_SEND_PACKET_LOOP	; LOOP
					;
	CALL	ATAPI_WAIT_BUSY_READY	; MAKE SURE DRIVE IS READY TO PROCEED
	RET	NC			; ERROR, RETURN
	IN	A,(IDECTRL)		; READ STATUS (FOR DELAY)
					;
	RET				;
	
	
	
;__DELAY24__________________________________________________________________________________________________________________________ 
;
; 	DELAY 24US
;________________________________________________________________________________________________________________________________
;
	
DELAY24:	
					; JP= 10T	
	PUSH	IX			; 15T
	POP	IX			; 14T
	PUSH	IX			; 15T
	POP	IX			; 14T
DELAY12:
	PUSH	IX			; 15T
	POP	IX			; 14T
	RET				; 10T


;__DELAYHSEC__________________________________________________________________________________________________________________________ 
;
; DELAY FOR 1/2 SECOND
;________________________________________________________________________________________________________________________________
;		
DELAYHSEC:
	LD	HL,00000H		; 65536
DELDM:
	NOP				; (4 T) 
	NOP				; (4 T)
	NOP				; (4 T)
	NOP				; (4 T)
	DEC	L			; (6 T)
	JP	NZ,DELDM		; (10 T) 24 T  8 MICROSECONDS AT 4 MHZ
	DEC	H			; (6 T)
	JP	NZ,DELDM		; (10 T) (8 US * 256) * 256  524288 US   5 SECONDS
	RET

; PIO 82C55 I/O IS DECODED TO PORT 60-67
;
PORTA		 .EQU 	60H
PORTB		 .EQU 	61H
PORTC		 .EQU 	62H
PIOCONT 	 .EQU 	63H	

;__IDESEGDISPLAY________________________________________________________________________________________
;
;  DISPLAY CONTENTS OF IDE LOGICAL BLOCK ADDRESS ON DSKY    
;____________________________________________________________________________________________________
IDESEGDISPLAY:
	LD	A, 82H			;
	OUT (PIOCONT),A			;
					;
	LD	A,(IDE_LBA3)		;
	AND	0FH			;
	LD	(DISPLAYBUF+6),A	;
	LD	A,(IDE_LBA3)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+7),A	;
					;
	LD	A,(IDE_LBA2)		;
	AND	0FH			;
	LD	(DISPLAYBUF+4),A	;
	LD	A,(IDE_LBA2)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+5),A	;
					;
	LD	A,(IDE_LBA1)		;
	AND	0FH			;
	LD	(DISPLAYBUF+2),A	;
	LD	A,(IDE_LBA1)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+3),A	;
	
	LD	A,(IDE_LBA0)		;
	AND	0FH			;
	LD	(DISPLAYBUF),A		;
	LD	A,(IDE_LBA0)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+1),A	;
	JP	SEGDISPLAY1		;
;__ATAPISEGDISPLAY________________________________________________________________________________________
;
;  DISPLAY CONTENTS OF ATAPI LOGICAL BLOCK ADDRESS ON DSKY    
;____________________________________________________________________________________________________
ATAPISEGDISPLAY:
	LD	A, 82H			;
	OUT (PIOCONT),A			;
					;
	LD	A,(LBA_TARGET_HI+1)	;
	AND	0FH			;
	LD	(DISPLAYBUF+6),A	;
	LD	A,(LBA_TARGET_HI+1)	;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+7),A	;
					;
	LD	A,(LBA_TARGET_HI)	;
	AND	0FH			;
	LD	(DISPLAYBUF+4),A	;
	LD	A,(LBA_TARGET_HI)	;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+5),A	;
					;
	LD	A,(LBA_TARGET_LO+1)	;
	AND	0FH			;
	LD	(DISPLAYBUF+2),A	;
	LD	A,(LBA_TARGET_LO+1)	;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+3),A	;
	
	LD	A,(LBA_TARGET_LO)	;
	AND	0FH			;
	LD	(DISPLAYBUF),A		;
	LD	A,(LBA_TARGET_LO)	;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+1),A	;

SEGDISPLAY1:				;
	LD	HL,DISPLAYBUF		;
	LD	BC,0007H		;
	ADD	HL,BC			;
	LD	B,08H			; SET DIGIT COUNT
	LD	A,40H			; SET CONTROL PORT 7218 TO OFF
	OUT	(PORTC),A		; OUTPUT
	CALL 	DELAY12			; WAIT
	LD	A,0D0H			; SET CONTROL TO 1111 (DATA COMING, HEX DECODE, DECODE, NORMAL)
	OUT	(PORTA),A		; OUTPUT TO PORT
	LD	A,80H			; STROBE WRITE PULSE WITH CONTROL=1
	OUT	(PORTC),A		; OUTPUT TO PORT
	CALL 	DELAY12			; WAIT
	LD	A,40H			; SET CONTROL PORT 7218 TO OFF
	OUT	(PORTC),A		; OUTPUT
	CALL 	DELAY12			; WAIT
SEGDISPLAY_LP:		
	LD	A,(HL)			; GET DISPLAY DIGIT
	OUT	(PORTA),A		; OUT TO PORTA
	LD	A,00H			; SET WRITE STROBE
	OUT	(PORTC),A		; OUT TO PORTC
	CALL	DELAY12			; DELAY
	LD	A,40H			; SET CONTROL PORT OFF
	OUT	(PORTC),A		; OUT TO PORTC
	CALL	DELAY12			; WAIT
	DEC	HL			; INC POINTER
	DJNZ	SEGDISPLAY_LP		; LOOP FOR NEXT DIGIT
	RET	
	
DISPLAYBUF:	 .DB 	01,02,03,04,05,06,07,08
		 .DB	00,00,00,00,00,00,00,00	
		 .DB	00,00,00,00,00,00,00,00	
		 .DB	00,00,00,00,00,00,00,00	
		 .DB	00,00,00,00,00,00,00,00	
FLOPPYSTACK:	 .DB	00
PARKSTACK:	 .DB	00,00,00,00
		
READ_DISK_PACKET
		 .DB	0A8H,00,00,00,00,01H,00,00,00,01H,00,00
WRITE_DISK_PACKET
		 .DB	2AH,00,00,00,00,11H,00,00,01H,00,00,00
ATAPI_REQUEST_SENSE
		 .DB	03H,00,00,00,011H,00,00,00,00,00,00,00


CPMSTART	.DW	00			; START OF CP/M
DRIVE		.DB	0			; DRIVE
TRACK		.DB 	0			; TRACK
HEAD		.DB	0			; HEAD
SECTOR		.DB	0			; SECTOR
LBA_TARGET_LO:	.DW 	0			; IDE HD PARTITION TARGET SECTOR (LOW 16 BITS)
LBA_TARGET_HI:	.DW 	0			; IDE HD PARTITION TARGET SECTOR (HI 16 BITS, 12 USED)
IDEDEVICE:	.DB 	0			; ATAPI DEVICE SELECTION FLAG

IDE_LBA0:	.DB 	0			; SET LBA 0:7
IDE_LBA1:	.DB 	0			; SET LBA 8:15
IDE_LBA2:	.DB 	0			; SET LBA 16:23
IDE_LBA3:	.DB 	0			; LOWEST 4 BITS USED ONLY TO ENABLE LBA MODE 
;
SECTOR_BUFFER:	.DS 520				; STORAGE FOR 512 BYTE IDE HD SECTOR

		
	
	
	
	
;__HXOUT_________________________________________________________________________________________________________________________ 
;
;	PRINT THE ACCUMULATOR CONTENTS AS HEX DATA ON THE SERIAL PORT
;________________________________________________________________________________________________________________________________
;
HXOUT:
	PUSH	BC			; SAVE BC
	LD	B,A			;
	RLC	A			; DO HIGH NIBBLE FIRST  
	RLC	A			;
	RLC	A			;
	RLC	A			;
	AND	0FH			; ONLY THIS NOW
	ADD	A,30H			; TRY A NUMBER
	CP	3AH			; TEST IT
	JR	C,OUT1			; IF CY SET PRINT 'NUMBER'
	ADD	A,07H			; MAKE IT AN ALPHA
OUT1:
	CALL	COUT			; SCREEN IT
	LD	A,B			; NEXT NIBBLE
	AND	0FH			; JUST THIS
	ADD	A,30H			; TRY A NUMBER
	CP	3AH			; TEST IT
	JR	C,OUT2			; PRINT 'NUMBER'
	ADD	A,07H			; MAKE IT ALPHA
OUT2:
	CALL	COUT			; SCREEN IT
	POP	BC			; RESTORE BC
	RET				;


;__SPACE_________________________________________________________________________________________________________________________ 
;
;	PRINT A SPACE CHARACTER ON THE SERIAL PORT
;________________________________________________________________________________________________________________________________
;
SPACE:
	PUSH	AF			; Store AF
	LD	A,20H			; LOAD A "SPACE"
	CALL	COUT			; SCREEN IT
	POP	AF			; RESTORE AF
	RET				; DONE

;__CRLF_________________________________________________________________________________________________________________________ 
;
;	PRINT A cr/lf
;________________________________________________________________________________________________________________________________
;
CRLF:
	PUSH	AF			; Store AF
	LD	A,0DH			; LOAD A "SPACE"
	CALL	COUT			; SCREEN IT
	LD	A,0AH			; LOAD A "SPACE"
	CALL	COUT			; SCREEN IT
	POP	AF			; RESTORE AF
	RET				; DONE

;__COUT_________________________________________________________________________________________________________________________ 
;
;	PRINT CONTENTS OF A 
;________________________________________________________________________________________________________________________________
;
COUT:
	PUSH	BC			;
	PUSH	AF			;
	PUSH	HL			;
	PUSH	DE			;
		
	LD	(COUT_BUFFER),A		;
	LD	DE,COUT_BUFFER		;
	LD	C,09H			; CP/M WRITE START STRING TO CONSOLE CALL
	CALL	0005H
	POP	DE			;
	POP	HL			;
	POP	AF			;
	POP	BC			;
	RET				; DONE




;__PHL_________________________________________________________________________________________________________________________ 
;
;	PRINT THE HL REG ON THE SERIAL PORT
;________________________________________________________________________________________________________________________________
;
PHL:
	LD	A,H			; GET HI BYTE
	CALL	HXOUT			; DO HEX OUT ROUTINE
	LD	A,L			; GET LOW BYTE
	CALL	HXOUT			; HEX IT
	CALL	SPACE			; 
	RET				; DONE  

COUT_BUFFER:
	.DB	00
	.DB	"$"

	.end
	